package com.agileboot.attendance.domain.holiday.service.impl;

import com.agileboot.attendance.domain.holiday.db.entity.Holiday;
import com.agileboot.attendance.domain.holiday.db.mapper.HolidayMapper;
import com.agileboot.attendance.domain.holiday.dto.HolidayDTO;
import com.agileboot.attendance.domain.holiday.dto.HolidayQueryDTO;
import com.agileboot.attendance.domain.holiday.service.IHolidayService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 节假日Service实现类
 *
 * @author ruoyi
 */
@Service
public class HolidayServiceImpl extends ServiceImpl<HolidayMapper, Holiday> implements IHolidayService {

    @Override
    public IPage<HolidayDTO> page(IPage<Holiday> page, HolidayQueryDTO queryDTO) {
        LambdaQueryWrapper<Holiday> queryWrapper = new LambdaQueryWrapper<>();
        
        // 构建查询条件
        if (StringUtils.hasText(queryDTO.getHolidayName())) {
            queryWrapper.like(Holiday::getHolidayName, queryDTO.getHolidayName());
        }
        
        if (StringUtils.hasText(queryDTO.getHolidayType())) {
            queryWrapper.eq(Holiday::getHolidayType, queryDTO.getHolidayType());
        }
        
        if (StringUtils.hasText(queryDTO.getIsOfficial())) {
            queryWrapper.eq(Holiday::getIsOfficial, queryDTO.getIsOfficial());
        }
        
        if (queryDTO.getStartDate() != null) {
            queryWrapper.ge(Holiday::getStartDate, queryDTO.getStartDate());
        }
        
        if (queryDTO.getEndDate() != null) {
            queryWrapper.le(Holiday::getEndDate, queryDTO.getEndDate());
        }
        
        if (queryDTO.getYear() != null) {
            LocalDate yearStart = LocalDate.of(queryDTO.getYear(), 1, 1);
            LocalDate yearEnd = LocalDate.of(queryDTO.getYear(), 12, 31);
            queryWrapper.between(Holiday::getStartDate, yearStart, yearEnd);
        }
        
        if (queryDTO.getMonth() != null && queryDTO.getYear() != null) {
            LocalDate monthStart = LocalDate.of(queryDTO.getYear(), queryDTO.getMonth(), 1);
            LocalDate monthEnd = monthStart.plusMonths(1).minusDays(1);
            queryWrapper.between(Holiday::getStartDate, monthStart, monthEnd);
        }
        
        // 按开始日期排序
        queryWrapper.orderByAsc(Holiday::getStartDate);
        
        // 执行分页查询
        IPage<Holiday> resultPage = this.page(page, queryWrapper);
        
        // 转换为DTO
        IPage<HolidayDTO> dtoPage = resultPage.convert(this::convertToDTO);
        
        return dtoPage;
    }

    @Override
    public HolidayDTO getInfo(Long holidayId) {
        Holiday holiday = this.getById(holidayId);
        return convertToDTO(holiday);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean add(HolidayDTO holidayDTO) {
        Holiday holiday = new Holiday();
        BeanUtils.copyProperties(holidayDTO, holiday);
        return this.save(holiday);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean update(HolidayDTO holidayDTO) {
        Holiday holiday = new Holiday();
        BeanUtils.copyProperties(holidayDTO, holiday);
        return this.updateById(holiday);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean delete(Long holidayId) {
        return this.removeById(holidayId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteBatch(Long[] holidayIds) {
        return this.removeByIds(Arrays.asList(holidayIds));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean importHolidays(Integer year) {
        // 这里可以实现从外部API或者预设的数据导入指定年份的节假日
        // 示例实现，实际应用中可能需要调用第三方API获取节假日数据
        List<Holiday> holidays = generateDefaultHolidays(year);
        return this.saveBatch(holidays);
    }

    @Override
    public boolean isHoliday(LocalDate date) {
        LambdaQueryWrapper<Holiday> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.le(Holiday::getStartDate, date)
                   .ge(Holiday::getEndDate, date);
        return this.count(queryWrapper) > 0;
    }

    @Override
    public List<HolidayDTO> getHolidaysByYear(Integer year) {
        LocalDate yearStart = LocalDate.of(year, 1, 1);
        LocalDate yearEnd = LocalDate.of(year, 12, 31);
        
        LambdaQueryWrapper<Holiday> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.between(Holiday::getStartDate, yearStart, yearEnd)
                   .orderByAsc(Holiday::getStartDate);
        
        List<Holiday> holidays = this.list(queryWrapper);
        return holidays.stream().map(this::convertToDTO).collect(Collectors.toList());
    }

    @Override
    public List<HolidayDTO> getHolidaysByMonth(Integer year, Integer month) {
        LocalDate monthStart = LocalDate.of(year, month, 1);
        LocalDate monthEnd = monthStart.plusMonths(1).minusDays(1);
        
        LambdaQueryWrapper<Holiday> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.between(Holiday::getStartDate, monthStart, monthEnd)
                   .orderByAsc(Holiday::getStartDate);
        
        List<Holiday> holidays = this.list(queryWrapper);
        return holidays.stream().map(this::convertToDTO).collect(Collectors.toList());
    }
    
    /**
     * 将实体转换为DTO
     */
    private HolidayDTO convertToDTO(Holiday holiday) {
        if (holiday == null) {
            return null;
        }
        HolidayDTO dto = new HolidayDTO();
        BeanUtils.copyProperties(holiday, dto);
        return dto;
    }
    
    /**
     * 生成默认的节假日数据（示例）
     */
    private List<Holiday> generateDefaultHolidays(Integer year) {
        List<Holiday> holidays = new ArrayList<>();
        
        // 元旦
        Holiday newYear = new Holiday();
        newYear.setHolidayName("元旦");
        newYear.setStartDate(LocalDate.of(year, 1, 1));
        newYear.setEndDate(LocalDate.of(year, 1, 1));
        newYear.setHolidayType("1");
        newYear.setIsOfficial("1");
        holidays.add(newYear);
        
        // 春节（农历，这里使用固定日期作为示例）
        Holiday springFestival = new Holiday();
        springFestival.setHolidayName("春节");
        springFestival.setStartDate(LocalDate.of(year, 2, 1));
        springFestival.setEndDate(LocalDate.of(year, 2, 7));
        springFestival.setHolidayType("1");
        springFestival.setIsOfficial("1");
        holidays.add(springFestival);
        
        // 清明节
        Holiday qingming = new Holiday();
        qingming.setHolidayName("清明节");
        qingming.setStartDate(LocalDate.of(year, 4, 5));
        qingming.setEndDate(LocalDate.of(year, 4, 5));
        qingming.setHolidayType("1");
        qingming.setIsOfficial("1");
        holidays.add(qingming);
        
        // 劳动节
        Holiday laborDay = new Holiday();
        laborDay.setHolidayName("劳动节");
        laborDay.setStartDate(LocalDate.of(year, 5, 1));
        laborDay.setEndDate(LocalDate.of(year, 5, 3));
        laborDay.setHolidayType("1");
        laborDay.setIsOfficial("1");
        holidays.add(laborDay);
        
        // 端午节（农历，这里使用固定日期作为示例）
        Holiday dragonBoat = new Holiday();
        dragonBoat.setHolidayName("端午节");
        dragonBoat.setStartDate(LocalDate.of(year, 6, 10));
        dragonBoat.setEndDate(LocalDate.of(year, 6, 10));
        dragonBoat.setHolidayType("1");
        dragonBoat.setIsOfficial("1");
        holidays.add(dragonBoat);
        
        // 中秋节（农历，这里使用固定日期作为示例）
        Holiday midAutumn = new Holiday();
        midAutumn.setHolidayName("中秋节");
        midAutumn.setStartDate(LocalDate.of(year, 9, 15));
        midAutumn.setEndDate(LocalDate.of(year, 9, 15));
        midAutumn.setHolidayType("1");
        midAutumn.setIsOfficial("1");
        holidays.add(midAutumn);
        
        // 国庆节
        Holiday nationalDay = new Holiday();
        nationalDay.setHolidayName("国庆节");
        nationalDay.setStartDate(LocalDate.of(year, 10, 1));
        nationalDay.setEndDate(LocalDate.of(year, 10, 7));
        nationalDay.setHolidayType("1");
        nationalDay.setIsOfficial("1");
        holidays.add(nationalDay);
        
        return holidays;
    }
} 